/*
 * Copyright 2016 Elvis Hew
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.elvishew.xlogsample;


import com.elvishew.xlog.LogLevel;
import com.elvishew.xlog.flattener.Flattener2;
import com.elvishew.xlog.flattener.PatternFlattener;
import com.elvishew.xlog.printer.Printer;
import com.elvishew.xlogsample.ResourceTable;
import ohos.agp.components.*;
import ohos.agp.utils.Color;
import ohos.app.Context;

import java.util.ArrayList;
import java.util.List;

/**
 * Display logs in a {@link}.
 */
public class RecyclerViewPrinter implements Printer {

    private ListContainer recyclerView;
    private LogAdapter adapter;
    private Context context;

    public RecyclerViewPrinter(Context context, ListContainer recyclerView) {
        // Setup the recycler view.
        adapter = new LogAdapter(context);
        recyclerView.setItemProvider(adapter);
        this.recyclerView = recyclerView;
    }

    @Override
    public void println(int logLevel, String tag, String msg) {
        // Append the log the the recycler view.
        adapter.addLog(new LogItem(System.currentTimeMillis(), logLevel, tag, msg));

        // Scroll to the bottom so we can see the newly-printed log.
        recyclerView.scrollTo(adapter.getCount() - 1);
    }

    private static class LogItem {

        static Flattener2 flattener = new PatternFlattener("{d HH:mm:ss.SSS} {l}/{t}: ");

        long timeMillis;
        int logLevel;
        String tag;
        String msg;

        private String label;

        LogItem(long timeMillis, int logLevel, String tag, String msg) {
            this.timeMillis = timeMillis;
            this.logLevel = logLevel;
            this.tag = tag;
            this.msg = msg;
        }

        /**
         * Get the label, with formatted time, log level and tag.
         * @return String
         */
        String getLabel() {
            // Lazily concat the label.
            if (label == null) {
                label = flattener.flatten(timeMillis, logLevel, tag, msg).toString();
            }
            return label;
        }
    }

    private static class LogAdapter extends RecycleItemProvider {

        private Context context;

        private List<LogItem> logs = new ArrayList<>();

        LogAdapter(Context context) {
            this.context = context;
        }

        void addLog(LogItem logItem) {
            logs.add(logItem);
//            notifyDataSetItemInserted(logs.size() - 1);
            notifyDataChanged();
        }

        /**
         * Get the highlight color for specific log level.
         *
         * @param logLevel the specific log level
         * @return the highlight color
         */
        private int getHighlightColor(int logLevel) {
            int hightlightColor;
            switch (logLevel) {
                case LogLevel.VERBOSE:
                    hightlightColor = 0xffbbbbbb;
                    break;
                case LogLevel.DEBUG:
                    hightlightColor = 0xff000000;
                    break;
                case LogLevel.INFO:
                    hightlightColor = 0xff6a8759;
                    break;
                case LogLevel.WARN:
                    hightlightColor = 0xffbbb529;
                    break;
                case LogLevel.ERROR:
                    hightlightColor = 0xffff6b68;
                    break;
                default:
                    hightlightColor = 0xffffff00;
                    break;
            }
            return hightlightColor;
        }

        @Override
        public int getCount() {
            return logs.size();
        }

        @Override
        public Object getItem(int i) {
            return null;
        }

        @Override
        public long getItemId(int i) {
            return 0;
        }

        @Override
        public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
            LogItem logItem = logs.get(i);
            LayoutScatter layoutScatter = LayoutScatter.getInstance(context);
            DependentLayout directionalLayout = (DependentLayout) layoutScatter.parse(com.elvishew.xlogsample.ResourceTable.Layout_item_log, null, false);
            Text label = (Text) directionalLayout.findComponentById(com.elvishew.xlogsample.ResourceTable.Id_label);
            Text message = (Text) directionalLayout.findComponentById(ResourceTable.Id_message);

            int color = getHighlightColor(logItem.logLevel);
            label.setTextColor(new Color(color));
            message.setTextColor(new Color(color));

            // Display label and message.
            label.setText(logItem.getLabel());
            message.setText(logItem.msg);

            if (i == 0) {
                directionalLayout.setHeight(80);
                directionalLayout.setVisibility(Component.HIDE);
            }

            return directionalLayout;
        }
    }

}
